package com.lyc.iotdb.common.iot;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.lyc.iotdb.common.annotation.IotTableName;
import lombok.extern.slf4j.Slf4j;
import org.apache.iotdb.isession.SessionDataSet;
import org.apache.iotdb.isession.util.Version;
import org.apache.iotdb.rpc.IoTDBConnectionException;
import org.apache.iotdb.rpc.StatementExecutionException;
import org.apache.iotdb.session.Session;
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
import org.apache.iotdb.tsfile.read.common.Field;
import org.apache.iotdb.tsfile.read.common.RowRecord;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import java.util.*;

import static org.apache.iotdb.mpp.rpc.thrift.TSchemaLimitLevel.TIMESERIES;

/**
 * @author kit
 */
@Component
@Slf4j
public class IotdbSessionConfig {

    /**
     * iotdb：用户名
     */
    @Value("${iotdb.username}")
    private String username;
    /**
     * iotdb：密码
     */
    @Value("${iotdb.password}")
    private String password;
    /**
     * iotdb：地址
     */
    @Value("${iotdb.ip}")
    private String ip;
    /**
     * iotdb：端口
     */
    @Value("${iotdb.port}")
    private Integer port;
    /**
     * iotdb：读取数
     */
    @Value("${iotdb.maxSize}")
    private Integer maxSize;

    private static Session session;

    private final long timeoutInMs = 30000;

    /**
     * 初始化
     *
     * @return Session
     * @throws IoTDBConnectionException    连接异常
     * @throws StatementExecutionException 执行异常
     */
    @Bean
    public Session getSession() throws StatementExecutionException, IoTDBConnectionException {
        if (session == null) {
            log.info("连接ioTDB");
            session = new Session.Builder()
                    .host(ip)
                    .port(port)
                    .username(username)
                    .password(password)
                    .version(Version.V_1_0)
                    .build();
            session.open(false);
            session.setFetchSize(maxSize);
            // 设置时区
            session.setTimeZone("+08:00");
        }
        return session;
    }


    /**
     * 节点路径
     *
     * @param records 记录
     * @return 记录
     */
    private List<String> getDeviceIds(List<? extends IotdbRecordable> records) {
        List<String> deviceIds = new ArrayList<>();
        for (IotdbRecordable iotdbRecordable : records) {
            IotdbRecord iotdbRecord = iotdbRecordable.toRecord();
            String deviceId = iotdbRecord.getDeviceId();
            deviceIds.add(deviceId);
        }
        return deviceIds;
    }

    /**
     * 时间戳
     *
     * @param records 记录
     * @return 记录
     */
    private List<Long> getTimes(List<? extends IotdbRecordable> records) {
        List<Long> times = new ArrayList<>();
        for (IotdbRecordable iotdbRecordable : records) {
            IotdbRecord iotdbRecord = iotdbRecordable.toRecord();
            times.add(iotdbRecord.getTime());
        }
        return times;
    }

    /**
     * 物理量 即：属性
     *
     * @param records 记录
     * @return 记录
     */
    private List<List<String>> getMeasurementsList(List<? extends IotdbRecordable> records) {
        List<List<String>> measurementsList = new ArrayList<>();
        for (IotdbRecordable iotdbRecordable : records) {
            IotdbRecord iotdbRecord = iotdbRecordable.toRecord();
            measurementsList.add(iotdbRecord.getMeasurementsList());
        }
        return measurementsList;
    }

    /**
     * 属性值 --- 属性必须与属性值一一对应
     *
     * @param records 记录
     * @return 记录
     */
    private List<List<Object>> getValuesList(List<? extends IotdbRecordable> records) {
        List<List<Object>> valuesList = new ArrayList<>();
        for (IotdbRecordable iotdbRecordable : records) {
            IotdbRecord iotdbRecord = iotdbRecordable.toRecord();
            valuesList.add(iotdbRecord.getValuesList());
        }

        return valuesList;
    }

    /**
     * 数据类型 BOOLEAN((byte)0), INT32((byte)1),INT64((byte)2),FLOAT((byte)3),DOUBLE((byte)4),TEXT((byte)5));
     *
     * @param records 记录
     * @return 记录
     */
    private List<List<TSDataType>> getTsDataType(List<? extends IotdbRecordable> records) {
        List<List<TSDataType>> valuesList = new ArrayList<>();
        for (IotdbRecordable iotdbRecordable : records) {
            IotdbRecord iotdbRecord = iotdbRecordable.toRecord();
            List<TSDataType> strList = new ArrayList<>();
            for (String str : iotdbRecord.getTypeList()) {
                strList.add(convertTypeByEntity(str));
            }
            valuesList.add(strList);
        }

        return valuesList;
    }

    /**
     * 实体数据类型转换
     *
     * @param type 属性类型
     * @return 类型
     */
    private TSDataType convertTypeByEntity(String type) {
        switch (type) {
            case "java.lang.Double":
            case "double":
                return TSDataType.DOUBLE;
            case "java.lang.Integer":
            case "int":
                return TSDataType.INT32;
            case "java.lang.Long":
            case "long":
                return TSDataType.INT64;
            case "java.lang.Boolean":
            case "boolean":
                return TSDataType.BOOLEAN;
            case "java.lang.Float":
            case "float":
                return TSDataType.FLOAT;
            default:
                return TSDataType.TEXT;
        }
    }

    /**
     * 批量插入
     *
     * @param records 类集合
     */
    public void insertRecords(List<? extends IotdbRecordable> records) {
        try {
            session.insertRecords(getDeviceIds(records), getTimes(records), getMeasurementsList(records), getTsDataType(records),
                    getValuesList(records));
        } catch (Exception e) {
            log.error("Iotdb插入异常:{}", e.getMessage());
        }
    }

    /**
     * 单个插入实体
     *
     * @param recordEntity 实体
     */
    public void insertRecord(IotdbRecordable recordEntity) {
        try {
            IotdbRecord iotdbRecord = recordEntity.toRecord();
            List<TSDataType> strList = new ArrayList<>();
            for (String str : iotdbRecord.getTypeList()) {
                strList.add(convertTypeByEntity(str));
            }
            session.insertRecord(iotdbRecord.getDeviceId(), iotdbRecord.getTime(), iotdbRecord.getMeasurementsList()
                    , strList, iotdbRecord.getValuesList());
        } catch (Exception e) {
            e.printStackTrace();
            log.error("Iotdb插入异常:{}", e.getMessage());
        }
    }

    /**
     * description: 根据SQL查询
     */
    public SessionDataSet query(String sql) throws StatementExecutionException, IoTDBConnectionException {
        return session.executeQueryStatement(sql, 30000);
    }

    /**
     * description: 删除分组 如 root.a1eaKSRpRty
     *
     * @param groupName：分组名称
     */
    public void deleteStorageGroup(String groupName) throws StatementExecutionException, IoTDBConnectionException {
        session.deleteStorageGroup(groupName);
    }

    /**
     * description: 根据TimeSeries删除  如：root.a1eaKSRpRty.CA3013A303A25467.breath  （个人理解：为具体的物理量）
     */
    public void deleteTimeSeries(String timeSeries) throws StatementExecutionException, IoTDBConnectionException {
        session.deleteTimeseries(timeSeries);
    }

    /**
     * description: 根据TimeSeries批量删除
     */
    public void deleteTimeSeriesList(List<String> timeseriesList) throws StatementExecutionException, IoTDBConnectionException {
        session.deleteTimeseries(timeseriesList);
    }

    /**
     * description: 根据分组批量删除
     */
    public void deleteStorageGroupList(List<String> storageGroupList) throws StatementExecutionException, IoTDBConnectionException {
        session.deleteStorageGroups(storageGroupList);
    }

    /**
     * description: 根据路径和结束时间删除 结束时间之前的所有数据
     */
    public void deleteDataByPathAndEndTime(String path, Long endTime) throws StatementExecutionException, IoTDBConnectionException {
        session.deleteData(path, endTime);
    }

    /**
     * description: 根据路径集合和结束时间批量删除 结束时间之前的所有数据
     */
    public void deleteDataByPathListAndEndTime(List<String> pathList, Long endTime) throws StatementExecutionException, IoTDBConnectionException {
        session.deleteData(pathList, endTime);
    }

    /**
     * description: 根据路径集合和时间段批量删除
     */
    public void deleteDataByPathListAndTime(List<String> pathList, Long startTime, Long endTime) throws StatementExecutionException, IoTDBConnectionException {
        session.deleteData(pathList, startTime, endTime);
    }

    /**
     * description: 根据SQL查询最新一条数据
     * author:zgy
     *
     * @param sql sql查询语句，count查询语句，一般为count(id) as ct 必须加as
     */
    public Map<String, Object> queryMapData(String sql) {
        Map<String, Object> rtMap = new HashMap<>();
        try {
            SessionDataSet sessionDataSetWrapper = session.executeQueryStatement(sql, timeoutInMs);
            List<String> columnNames = sessionDataSetWrapper.getColumnNames();
            List<Map<String, Object>> rtList = packagingData(sessionDataSetWrapper, columnNames);
            if (!rtList.isEmpty()) {
                rtMap = rtList.get(0);
            }
        } catch (Exception e) {
            log.error("查询Map返回数据集数据异常,异常SQL>{};：{}", sql, e.toString());
        }
        return rtMap;
    }

    /**
     * description: 根据SQL查询最新一条数据
     * author:zgy
     *
     * @param sql   sql查询语句，查询条件最前面加 last
     * @param clazz 类
     */
    public IotdbRecordable queryLastData(String sql, Class<? extends IotdbRecordable> clazz) {
        Map<String, Object> rtMap = new HashMap<>();
        try {
            IotTableName iotTableName = clazz.getAnnotation(IotTableName.class);
            String tableName = iotTableName.value();
            SessionDataSet sessionDataSetWrapper = session.executeQueryStatement(sql, timeoutInMs);
            List<String> columnNames = sessionDataSetWrapper.getColumnNames().subList(1, sessionDataSetWrapper.getColumnNames().size());
            List<Map<String, Object>> rtList = packagingData(sessionDataSetWrapper, columnNames);
            for (Map<String, Object> map : rtList) {
                if (map.get(TIMESERIES) != null) {
                    rtMap.put(map.get(TIMESERIES).toString().replace(tableName + ".", ""), map.get("Value"));
                }
            }
        } catch (Exception e) {
            log.error(IotdbConstant.EXCEPTION_SQL, clazz, sql, e.toString());
        }
        return JSON.parseObject(JSON.toJSONString(rtMap), clazz);
    }

    /**
     * description: 根据SQL查询最新一条数据
     * author:zgy
     *
     * @param sql       sql查询语句，查询条件最前面加 last
     * @param tableName Iotdb表名
     * @return
     */
    public Map<String, Object> queryLastData(String sql, String tableName) {
        Map<String, Object> rtMap = new HashMap<>();
        try {

            SessionDataSet sessionDataSetWrapper = session.executeQueryStatement(sql, timeoutInMs);
            List<String> columnNames = sessionDataSetWrapper.getColumnNames().subList(1, sessionDataSetWrapper.getColumnNames().size());
            List<Map<String, Object>> rtList = packagingData(sessionDataSetWrapper, columnNames);
            for (Map<String, Object> map : rtList) {
                if (map.get(TIMESERIES) != null) {
                    rtMap.put(map.get(TIMESERIES).toString().replace(tableName + ".", ""), map.get("Value"));
                }
            }
        } catch (Exception e) {
            log.error(IotdbConstant.EXCEPTION_SQL, tableName, sql, e.toString());
        }
        return rtMap;
    }

    /**
     * description: 根据SQL查询
     * author: zgy
     *
     * @param sql   sql查询语句
     * @param clazz 类.
     */
    public List<?> queryListData(String sql, Class<? extends IotdbRecordable> clazz) {
        List<IotdbRecordable> rtList = new ArrayList<>();
        try {
            //获取实体类注释表名
            IotTableName iotTableName = clazz.getAnnotation(IotTableName.class);
            String tableName = iotTableName.value();
            //获取查询条件是否是*全查
            String selectParam = sql.substring(6, sql.indexOf("from")).trim();
            SessionDataSet sessionDataSetWrapper = session.executeQueryStatement(sql, timeoutInMs);
            List<String> columnNames = sessionDataSetWrapper.getColumnNames();
            //判断如果第一个列值为Time时间戳去掉
            if (Objects.equals(columnNames.get(0), "Time")) {
                columnNames.remove(0);
            }
            List<Map<String, Object>> list = packagingData(sessionDataSetWrapper, columnNames);
            for (Map<String, Object> map : list) {
                //如果是*全查需要进行key值得转换
                if (StrUtil.contains(selectParam, IotdbConstant.STR_ASTERISK)) {
                    Map<String, Object> rtMap = new HashMap<>();
                    //循环进行key值得转换
                    for (Map.Entry<String, Object> it : map.entrySet()) {
                        rtMap.put(it.getKey().replace(tableName + StrUtil.DOT, StrUtil.EMPTY), it.getValue());
                    }
                    //map转换实体
                    rtList.add(JSON.parseObject(JSON.toJSONString(rtMap), clazz));
                } else {//如果不为*则依照别名来查
                    //map转换实体
                    rtList.add(JSON.parseObject(JSON.toJSONString(map), clazz));
                }
            }
        } catch (Exception e) {
            log.error(IotdbConstant.EXCEPTION_SQL, clazz, sql, e.toString());
        }
        return rtList;
    }

    /**
     * 根据SQL查询
     *
     * @param sql        sql查询语句
     * @param params     参数
     * @param countField 统计字段。默认为count(*)
     * @param clazz      类.
     * @return 分页查询结果
     */
    public IotdbPage queryPage(String sql, Map<String, Object> params, String countField, Class<? extends IotdbRecordable> clazz) {
        // 分页返回结果
        IotdbPage rstPage = null;
        try {
            // 查询总条数
            int totalCount = getTotalCount(sql, countField);
            // 拼接分页
            // 默认当前页为1
            int curPage = 1;
            // 默认每页10条
            int limit = 10;
            if (ObjectUtil.isNotEmpty(params.get(IotdbConstant.PAGE))) {
                curPage = Convert.toInt(params.get(IotdbConstant.PAGE));
            }
            if (ObjectUtil.isNotEmpty(params.get(IotdbConstant.LIMIT))) {
                limit = Convert.toInt(params.get(IotdbConstant.LIMIT));
            }

            if (StrUtil.contains(sql, ';')) {
                sql = StrUtil.removeAll(sql, ';');
            }
            // 分页sql
            sql = sql + " limit " + limit + " offset " + (curPage - 1) * limit;
            log.info("执行查询sql={}", sql);
            // 获取实体类注释表名
            IotTableName iotTableName = clazz.getAnnotation(IotTableName.class);
            String tableName = iotTableName.value();
            // 获取查询条件是否是*全查
            String selectParam = sql.substring(6, sql.indexOf("from")).trim();
            SessionDataSet sessionDataSetWrapper = session.executeQueryStatement(sql, timeoutInMs);
            List<String> columnNames = sessionDataSetWrapper.getColumnNames();
            //判断如果第一个列值为Time时间戳去掉
            if (Objects.equals(columnNames.get(0), "Time")) {
                columnNames.remove(0);
            }
            List<Map<String, Object>> list = packagingData(sessionDataSetWrapper, columnNames);
            List<IotdbRecordable> rtList = new ArrayList<>();
            for (Map<String, Object> map : list) {
                //如果是*全查需要进行key值得转换
                if (StrUtil.contains(selectParam, IotdbConstant.STR_ASTERISK)) {
                    Map<String, Object> rtMap = new HashMap<>();
                    //循环进行key值得转换
                    for (Map.Entry<String, Object> it : map.entrySet()) {
                        rtMap.put(it.getKey().replace(tableName + ".", ""), it.getValue());
                    }
                    // map转换实体
                    rtList.add(JSON.parseObject(JSON.toJSONString(rtMap), clazz));
                } else {// 如果不为*则依照别名来查
                    // map转换实体
                    rtList.add(JSON.parseObject(JSON.toJSONString(map), clazz));
                }
            }
            rstPage = new IotdbPage(rtList, totalCount, limit, curPage);
        } catch (StatementExecutionException | IoTDBConnectionException e) {
            log.error(IotdbConstant.EXCEPTION_SQL, clazz, sql, e.toString());
            throw new RuntimeException("sql执行异常，请检查");
        }
        return rstPage;
    }

    /**
     * 根据SQL查询 List集合
     *
     * @param sql       查询条件
     * @param tableName 表名
     * @return
     */
    public IotdbPage queryPage(String sql, Map<String, Object> params, String countField, String tableName) {
        // 分页返回结果
        IotdbPage rstPage = null;
        try {
            // 获取查询总条数
            int totalCount = getTotalCount(sql, countField);
            // 拼接分页
            // 默认当前页为1
            int curPage = 1;
            // 默认每页10条
            int limit = 10;
            if (ObjectUtil.isNotEmpty(params.get(IotdbConstant.PAGE))) {
                curPage = Convert.toInt(params.get(IotdbConstant.PAGE));
            }
            if (ObjectUtil.isNotEmpty(params.get(IotdbConstant.LIMIT))) {
                limit = Convert.toInt(params.get(IotdbConstant.LIMIT));
            }
            int offset = (curPage - 1) * limit;
            if (StrUtil.contains(sql, ';')) {
                sql = StrUtil.removeAll(sql, ';');
            }
            // 分页sql
            sql = sql + " limit " + limit + " offset " + offset;
            log.info("执行查询sql={}", sql);
            SessionDataSet sessionDataSetWrapper = session.executeQueryStatement(sql, timeoutInMs);
            //获取查询条件是否是*全查
            List<String> columnNames = sessionDataSetWrapper.getColumnNames();
            //判断如果第一个列值为Time时间戳去掉
            if (Objects.equals(columnNames.get(0), "Time")) {
                columnNames.remove(0);
            }
            List<Map<String, Object>> itsList = packagingData(sessionDataSetWrapper, columnNames);
            List<Map<String, Object>> rtList = new ArrayList<>();
            // 获取查询条件是否是*全查
            String selectParam = sql.substring(6, sql.indexOf("from")).trim();
            for (Map<String, Object> map : itsList) {
                //如果是*全查需要进行key值得转换
                if (Objects.equals("*", selectParam)) {
                    Map<String, Object> rtMap = new HashMap<>();
                    //循环进行key值得转换
                    for (Map.Entry<String, Object> it : map.entrySet()) {
                        rtMap.put(it.getKey().replace(tableName + ".", ""), it.getValue());
                    }
                    //map转换实体
                    rtList.add(rtMap);
                } else {//如果不为*则依照别名来查
                    //map转换实体
                    rtList.add(map);
                }
            }
            rstPage = new IotdbPage(rtList, totalCount, limit, curPage);
        } catch (StatementExecutionException | IoTDBConnectionException e) {
            log.error(IotdbConstant.EXCEPTION_SQL, tableName, sql, e.toString());
        }
        return rstPage;
    }

    /**
     * 根据SQL查询 List集合
     *
     * @param sql       查询条件
     * @param tableName 表名
     * @return
     */
    public List<Map<String, Object>> query(String sql, String tableName) {
        List<Map<String, Object>> rtList = new ArrayList<>();
        try {
            SessionDataSet sessionDataSetWrapper = session.executeQueryStatement(sql, timeoutInMs);
            //获取查询条件是否是*全查
            String selectParam = sql.substring(6, sql.indexOf("from")).trim();
            List<String> columnNames = sessionDataSetWrapper.getColumnNames();
            //判断如果第一个列值为Time时间戳去掉
            if (Objects.equals(columnNames.get(0), "Time")) {
                columnNames.remove(0);
            }
            List<Map<String, Object>> itsList = packagingData(sessionDataSetWrapper, columnNames);
            for (Map<String, Object> map : itsList) {
                //如果是*全查需要进行key值得转换
                if (Objects.equals("*", selectParam)) {
                    Map<String, Object> rtMap = new HashMap<>();
                    //循环进行key值得转换
                    for (Map.Entry<String, Object> it : map.entrySet()) {
                        rtMap.put(it.getKey().replace(tableName + ".", ""), it.getValue());
                    }
                    //map转换实体
                    rtList.add(rtMap);
                } else {//如果不为*则依照别名来查
                    //map转换实体
                    rtList.add(map);
                }
            }
        } catch (Exception e) {
            log.error(IotdbConstant.EXCEPTION_SQL, tableName, sql, e.toString());
            return rtList;
        }
        return rtList;
    }

    /**
     * 封装处理数据
     *
     * @param sessionDataSet
     * @param titleList
     * @throws StatementExecutionException
     * @throws IoTDBConnectionException
     */
    private List<Map<String, Object>> packagingData(SessionDataSet sessionDataSet, List<String> titleList)
            throws StatementExecutionException, IoTDBConnectionException {
        int fetchSize = sessionDataSet.getFetchSize();
        List<Map<String, Object>> rtList = new ArrayList<>();
        if (fetchSize > 0) {
            while (sessionDataSet.hasNext()) {
                Map<String, Object> rtMap = new HashMap<>();
                RowRecord next = sessionDataSet.next();
                List<Field> fields = next.getFields();
                String timeString = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(next.getTimestamp());
                rtMap.put(IotdbConstant.TIMESERIES_TIMESTAMP, next.getTimestamp());
                rtMap.put(IotdbConstant.TIMESERIES_TIMESTAMPSTR, timeString);
                for (int i = 0; i < fields.size(); i++) {
                    Field field = fields.get(i);
                    // 这里的需要按照类型获取
                    if (field.getDataType() == null || field.getObjectValue(field.getDataType()) == null) {
                        rtMap.put(titleList.get(i), null);
                    } else {
                        rtMap.put(titleList.get(i), field.getObjectValue(field.getDataType()).toString());
                    }
                }
                rtList.add(rtMap);
            }
        }
        return rtList;
    }


    /**
     * 分页查询获取统计值
     *
     * @param sql        执行sql（注意：from小写）
     * @param countField 可以指定统计字段，不指定默认为count(*)
     * @return 总条数
     * @throws StatementExecutionException 执行异常
     * @throws IoTDBConnectionException    连接异常
     */
    private int getTotalCount(String sql, String countField) throws StatementExecutionException, IoTDBConnectionException {
        if (StrUtil.isEmpty(countField)) {
            countField = "*";
        }
        log.info("countsql 截取 {}", StrUtil.subAfter(sql, "from", true));
        // 组织统计语句
        String countSql = StrUtil.format(IotdbConstant.COUNT_SQL, countField, StrUtil.subAfter(sql, "from", true));
        log.info("执行统计sql={}", countSql);
        SessionDataSet sessionDataSetCount = session.executeQueryStatement(countSql);
        int totalCount = 0;
        int tmp = 0;
        if (sessionDataSetCount.getFetchSize() > 0) {
            // 统计获取时间序列最大数返回
            while (sessionDataSetCount.hasNext()) {
                RowRecord next = sessionDataSetCount.next();
                tmp = (int) next.getFields().get(0).getLongV();
                if (tmp > totalCount) {
                    totalCount = tmp;
                }
            }
        }
        return totalCount;
    }

    /**
     * 执行分页查询语句
     *
     * @param sql    执行sql（注意：from小写）
     * @param params 参数
     * @return rst
     */
    private List<Map<String, Object>> executePageQuery(String sql, Map<String, Object> params) throws IoTDBConnectionException, StatementExecutionException {
        // 拼接分页
        // 默认当前页为1
        int curPage = 1;
        // 默认每页10条
        int limit = 10;
        if (ObjectUtil.isNotEmpty(params.get(IotdbConstant.PAGE))) {
            curPage = Convert.toInt(params.get(IotdbConstant.PAGE));
        }
        if (ObjectUtil.isNotEmpty(params.get(IotdbConstant.LIMIT))) {
            limit = Convert.toInt(params.get(IotdbConstant.LIMIT));
        }
        int offset = (curPage - 1) * limit;
        if (StrUtil.contains(sql, ';')) {
            sql = StrUtil.removeAll(sql, ';');
        }
        // 分页sql
        sql = sql + " limit " + limit + " offset " + offset;
        log.info("执行查询sql={}", sql);
        SessionDataSet sessionDataSetWrapper = session.executeQueryStatement(sql, timeoutInMs);
        //获取查询条件是否是*全查
        List<String> columnNames = sessionDataSetWrapper.getColumnNames();
        //判断如果第一个列值为Time时间戳去掉
        if (Objects.equals(columnNames.get(0), "Time")) {
            columnNames.remove(0);
        }
        List<Map<String, Object>> list = packagingData(sessionDataSetWrapper, columnNames);
        return list;
    }
}
